home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / MEMORY.SWG / 0051_Stack usage report source.pas < prev    next >
Pascal/Delphi Source File  |  1994-05-25  |  3KB  |  103 lines

  1. {
  2. The program StackUse below measures your EXACT stack usage
  3. (REAL mode only). Make sure the constant Ssize is equal to the
  4. actual physical stack size as defined with the $M directive or
  5. in the Turbo Pascal IDE settings (the Options/MemorySizes menu).
  6.  
  7. For your own programs, you just need to call Initstack at the very
  8. start, then call StackReport whenever you want - or calculate for
  9. yourself, (Ssize-(VirginStack-StackLimit)) equals the number of
  10. stack bytes actually used.
  11.  
  12. Sptr gives you the current stack pointer, and StackLimit is
  13. a TP system variable (WORD) that contains the current bottom of
  14. of the stack. StackLimit is usually zero, but some 'sneaky'
  15. programs raise it so they can hide something there - for example,
  16. c1;0compiling your program using the replacement run-time libraries
  17. by Norbert Juffa can raise the StackLimit to 512.
  18. The stack is filled from top to bottom, so a stack overflow
  19. means Sptr <= StackLimit.
  20. UseStack is just an example of a procedure that makes heavy
  21. use of the stack.
  22.  
  23. This code can be freely included in any FAQ,
  24. SNIPPETS, SWAG or what-have-you.
  25.  
  26.  Erik de Neve
  27.  Internet:    100121.1070@compuserve.com
  28.  
  29.  Last update:  March  8, 1994
  30.  
  31. { -*- CUT HERE -*- }
  32.  
  33. Program StackUse;
  34.  
  35. {$M 16384,0,0 }
  36.  
  37. CONST
  38.  Ssize = 16384; {should match stack size as set by the $M directive }
  39.  
  40. Procedure Initstack;  { fills unused stack with marker value }
  41.  Assembler;
  42.  ASM
  43.    PUSH SS      { SS = the stack segment }
  44.    POP  ES
  45.    MOV  DI,StackLimit
  46.    MOV  CX,SP    { SP = stack pointer register }
  47.    SUB  CX,DI
  48.    MOV  AL,77    { arbitrary marker value }
  49.    CLD
  50.    REP  STOSB
  51.  END;
  52.  
  53. Function VirginStack:word;  { finds highest unused byte on stack }
  54.  Assembler;
  55.  ASM
  56.    PUSH SS
  57.    POP  ES
  58.    MOV  DI,StackLimit   { is usually 0 }
  59.    MOV  CX,SP
  60.    SUB  CX,DI
  61.    MOV  AL,77  { marker value, must be the same as in InitStack }
  62.    CLD
  63.    REPE SCASB  { scan empty stack }
  64.    DEC  DI     { adjust for last non-matching byte in the scan }
  65.    MOV  AX,DI
  66.  END;
  67.  
  68.  
  69. Procedure StackReport; { Reports all sizes in bytes and percentages }
  70. begin
  71.  WriteLn('Stack Bottom : ',StackLimit:6);
  72.  WriteLn('Current SP   : ',Sptr:6);
  73.  WriteLn('Total Stack  : ',Ssize:6,
  74.  ' bytes   = 100.00 %');
  75.  WriteLn('  Now used   : ',Ssize-(Sptr-StackLimit):6,
  76.  ' bytes   = ',(Ssize-(Sptr-StackLimit))/Ssize *100:6:2,' %');
  77.  WriteLn(' Ever used   : ',Ssize-(VirginStack-StackLimit):6,
  78.  ' bytes   = ',(Ssize-(VirginStack-StackLimit))/Ssize *100:6:2,' %');
  79.  WriteLn('Never used   : ',(VirginStack-StackLimit):6,
  80.  ' bytes   = ',(VirginStack-StackLimit)/Ssize *100:6:2,' %');
  81. end;
  82.  
  83.  
  84. Procedure UseStack(CNT:WORD); Assembler;  { example stack usage }
  85.  ASM
  86.    MOV  AX,0    {dummy value}
  87.    MOV  CX,CNT
  88. @pushit:        {perform CNT PUSHes}
  89.    PUSH AX
  90.    LOOP @pushit
  91.    MOV  CX,CNT
  92. @poppit:        {perform CNT POPs}
  93.    POP  AX
  94.    LOOP @poppit
  95.  END;
  96.  
  97.  
  98. BEGIN
  99.  InitStack;      { prepare stack }
  100.  UseStack(1000); { perform a number of PUSHes and POPs }
  101.  StackReport;    { report stack usage }
  102. END.
  103.